πŸ•ΈοΈ Ada Research Browser

DI_ARCHITECTURE_DIAGRAM.md
← Back

Dependency Injection Architecture Diagrams

Current Architecture (Before DI)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           main()                               β”‚
β”‚                       (toolkit.go)                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
                      β”‚ Creates App struct
                      β”‚
                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          App Struct                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Fields:                                                       β”‚
β”‚  - menu: *Menu (created in main)                               β”‚
β”‚  - reader: *RegistryReader (created in App.init())             β”‚
β”‚  - config: *AppConfig (created in main)                        β”‚
β”‚  - outputDir, logsDir, evidenceDir, reportsDir, exeDir         β”‚
β”‚                                                                β”‚
β”‚  Methods:                                                      β”‚
β”‚  - init() - Creates reader, sets global logger                β”‚
β”‚  - executeReport() - Creates HTMLReport & EvidenceLogger       β”‚
β”‚  - executeReportQuiet() - Duplicate of executeReport()         β”‚
β”‚  - runReports(), viewHTMLReports(), etc.                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β”‚ executeReport() calls
            β”‚
            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     Direct Dependencies                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                β”‚
β”‚  pkg.LoadConfig(configPath)                                    β”‚
β”‚       ↓                                                        β”‚
β”‚  pkg.NewHTMLReport(reportName, outputDir)                      β”‚
β”‚       ↓                                                        β”‚
β”‚  htmlReport.SetRegistryReader(app.reader)  ← TIGHT COUPLING    β”‚
β”‚       ↓                                                        β”‚
β”‚  pkg.NewEvidenceLogger(evidenceDir, reportType)                β”‚
β”‚       ↓                                                        β”‚
β”‚  evidenceLogger.GatherMachineInfo(app.reader)                  β”‚
β”‚                                                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

                      ⚠️ PROBLEMS ⚠️

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. Global State: slog.SetDefault(logger) in init()            β”‚
β”‚    β†’ Cannot run tests in parallel                             β”‚
β”‚    β†’ Hidden dependency on global logger                        β”‚
β”‚                                                                β”‚
β”‚ 2. Direct Instantiation: Components create their own deps     β”‚
β”‚    β†’ Hard to mock for testing                                 β”‚
β”‚    β†’ Tight coupling between layers                            β”‚
β”‚                                                                β”‚
β”‚ 3. No Interfaces: All concrete types                          β”‚
β”‚    β†’ Cannot swap implementations                              β”‚
β”‚    β†’ Violates Dependency Inversion Principle                  β”‚
β”‚                                                                β”‚
β”‚ 4. Mixed Concerns: App does initialization + business logic   β”‚
β”‚    β†’ Single Responsibility Principle violated                 β”‚
β”‚    β†’ Hard to test business logic in isolation                 β”‚
β”‚                                                                β”‚
β”‚ 5. Code Duplication: executeReport() vs executeReportQuiet()  β”‚
β”‚    β†’ Maintenance nightmare                                    β”‚
β”‚    β†’ Bug fixes must be applied twice                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Target Architecture (After DI)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                            main()                                β”‚
β”‚                        (toolkit.go)                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β”‚ 1. Parse flags & create AppConfig
         β”‚ 2. Setup logger (NO global state)
         β”‚ 3. Create directories
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    NewDependencies(config, logger)               β”‚
β”‚                      (dependencies.go)                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Returns Dependencies struct containing:                         β”‚
β”‚                                                                  β”‚
β”‚  β€’ Logger: *slog.Logger                                          β”‚
β”‚  β€’ Config: *AppConfig                                            β”‚
β”‚  β€’ RegistryService: pkg.RegistryService (interface)              β”‚
β”‚  β€’ UIService: pkg.UIService (interface)                          β”‚
β”‚  β€’ ConfigService: pkg.ConfigService (interface)                  β”‚
β”‚  β€’ FileService: pkg.FileService (interface)                      β”‚
β”‚                                                                  β”‚
β”‚  Methods:                                                        β”‚
β”‚  β€’ Validate() - Ensures all deps are non-nil                    β”‚
β”‚  β€’ Clone(config) - Creates copy for testing                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β”‚ Dependencies passed to
            β”‚
            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      NewApp(deps)                                β”‚
β”‚                      (toolkit.go)                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  App Struct:                                                     β”‚
β”‚  - deps: *Dependencies                                           β”‚
β”‚  - factory: *ServiceFactory                                      β”‚
β”‚                                                                  β”‚
β”‚  Methods (Business Logic Only):                                 β”‚
β”‚  - runInteractive() - Interactive menu loop                     β”‚
β”‚  - runReports() - Uses deps.UIService, factory                  β”‚
β”‚  - viewHTMLReports() - Uses deps.FileService                    β”‚
β”‚  - listReportsCLI() - Uses deps.FileService                     β”‚
β”‚  - runReportCLI() - Uses ReportRunner                           β”‚
β”‚                                                                  β”‚
β”‚  βœ… NO initialization logic                                     β”‚
β”‚  βœ… NO direct component creation                                β”‚
β”‚  βœ… All dependencies injected                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β”‚ Uses factory to create services
            β”‚
            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               ServiceFactory (factory.go)                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  CreateReportService(title, outputDir) β†’ ReportService           β”‚
β”‚       Returns: pkg.NewHTMLReport(title, outputDir, logger, reg)  β”‚
β”‚                                                                  β”‚
β”‚  CreateEvidenceService(dir, type) β†’ EvidenceService              β”‚
β”‚       Returns: pkg.NewEvidenceLogger(dir, type, logger)          β”‚
β”‚                                                                  β”‚
β”‚  CreateReportRunner() β†’ *ReportRunner                            β”‚
β”‚       Returns: NewReportRunner(deps)                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β”‚ Factory creates
            β”‚
            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    ReportRunner Service                          β”‚
β”‚                  (report_runner.go)                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Constructor:                                                    β”‚
β”‚  NewReportRunner(deps *Dependencies) *ReportRunner               β”‚
β”‚                                                                  β”‚
β”‚  Methods:                                                        β”‚
β”‚  ExecuteReport(configFile, quiet) error                          β”‚
β”‚      1. Uses deps.ConfigService.LoadConfig()                    β”‚
β”‚      2. Uses factory.CreateReportService()                      β”‚
β”‚      3. Uses factory.CreateEvidenceService()                    β”‚
β”‚      4. Uses deps.RegistryService for queries                   β”‚
β”‚      5. Generates report and evidence                           β”‚
β”‚                                                                  β”‚
β”‚  βœ… Single responsibility: Execute reports                      β”‚
β”‚  βœ… Testable with mocks                                         β”‚
β”‚  βœ… No code duplication                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Interface Layer

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    pkg/interfaces.go                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                β”‚
β”‚  interface RegistryService {                                   β”‚
β”‚      ReadString(...)                                           β”‚
β”‚      ReadInteger(...)                                          β”‚
β”‚      ReadBinary(...)                                           β”‚
β”‚      ReadStrings(...)                                          β”‚
β”‚      ReadValue(...)                                            β”‚
β”‚      BatchRead(...)                                            β”‚
β”‚  }                                                             β”‚
β”‚                                                                β”‚
β”‚  interface ReportService {                                     β”‚
β”‚      Generate() error                                          β”‚
β”‚      AddResult(...)                                            β”‚
β”‚      AddResultWithDetails(...)                                 β”‚
β”‚      SetMetadata(...)                                          β”‚
β”‚      GetOutputPath() string                                    β”‚
β”‚  }                                                             β”‚
β”‚                                                                β”‚
β”‚  interface EvidenceService {                                   β”‚
β”‚      GatherMachineInfo(RegistryService) error                  β”‚
β”‚      LogResult(...)                                            β”‚
β”‚      Finalize() error                                          β”‚
β”‚      GetSummaryText() string                                   β”‚
β”‚      GetLogPath() string                                       β”‚
β”‚  }                                                             β”‚
β”‚                                                                β”‚
β”‚  interface UIService {                                         β”‚
β”‚      ShowHeader()                                              β”‚
β”‚      ShowMainMenu() int                                        β”‚
β”‚      ShowReportMenuDynamic(...) int                            β”‚
β”‚      ShowError(string)                                         β”‚
β”‚      ShowSuccess(string)                                       β”‚
β”‚      Pause()                                                   β”‚
β”‚      GetIntInput() int                                         β”‚
β”‚      // ...                                                    β”‚
β”‚  }                                                             β”‚
β”‚                                                                β”‚
β”‚  interface ConfigService {                                     β”‚
β”‚      LoadConfig(path) (*Config, error)                         β”‚
β”‚      ParseRootKey(string) (registry.Key, error)                β”‚
β”‚  }                                                             β”‚
β”‚                                                                β”‚
β”‚  interface FileService {                                       β”‚
β”‚      FindReportsDirectory(exeDir) string                       β”‚
β”‚      ResolveDirectory(dir, exeDir) string                      β”‚
β”‚      ListReports(reportsDir) ([]ReportInfo, error)             β”‚
β”‚      OpenBrowser(url) error                                    β”‚
β”‚      OpenFile(path) error                                      β”‚
β”‚  }                                                             β”‚
β”‚                                                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                  β”‚
                                  β”‚ Implemented by
                                  β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                           β”‚
                    β–Ό                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Production Implementationsβ”‚   β”‚    Mock Implementations   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                           β”‚   β”‚                           β”‚
β”‚ RegistryReader            β”‚   β”‚ MockRegistryService       β”‚
β”‚ HTMLReport                β”‚   β”‚ MockReportService         β”‚
β”‚ EvidenceLogger            β”‚   β”‚ MockEvidenceService       β”‚
β”‚ Menu                      β”‚   β”‚ MockUIService             β”‚
β”‚ ConfigServiceImpl         β”‚   β”‚ MockConfigService         β”‚
β”‚ FileServiceImpl           β”‚   β”‚ MockFileService           β”‚
β”‚                           β”‚   β”‚                           β”‚
β”‚ Used in production        β”‚   β”‚ Used in unit tests        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Dependency Flow Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         Application Layers                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Layer 1: Entry Point
β”œβ”€ main() (toolkit.go)
β”‚  └─ Responsibilities:
β”‚     β€’ Parse CLI flags
β”‚     β€’ Create configuration
β”‚     β€’ Setup logger
β”‚     β€’ Wire dependencies
β”‚     β€’ Start application

Layer 2: Dependency Container
β”œβ”€ Dependencies (dependencies.go)
β”‚  └─ Contains:
β”‚     β€’ Logger (*slog.Logger)
β”‚     β€’ Config (*AppConfig)
β”‚     β€’ All service interfaces
β”‚  └─ Methods:
β”‚     β€’ Validate() - Ensure all deps set
β”‚     β€’ Clone() - For testing

Layer 3: Application Core
β”œβ”€ App (toolkit.go)
β”‚  └─ Responsibilities:
β”‚     β€’ Interactive menu handling
β”‚     β€’ CLI command routing
β”‚     β€’ User interaction coordination
β”‚  └─ Dependencies:
β”‚     β€’ deps *Dependencies
β”‚     β€’ factory *ServiceFactory

Layer 4: Service Layer
β”œβ”€ ServiceFactory (factory.go)
β”‚  └─ Creates:
β”‚     β€’ ReportService instances
β”‚     β€’ EvidenceService instances
β”‚     β€’ ReportRunner instances
β”‚
β”œβ”€ ReportRunner (report_runner.go)
β”‚  └─ Responsibilities:
β”‚     β€’ Execute compliance reports
β”‚     β€’ Coordinate services
β”‚     β€’ Handle errors
β”‚  └─ Dependencies:
β”‚     β€’ deps *Dependencies
β”‚     β€’ factory *ServiceFactory

Layer 5: Business Logic (pkg/)
β”œβ”€ Services (implement interfaces)
β”‚  β”œβ”€ RegistryReader - Registry operations
β”‚  β”œβ”€ HTMLReport - Report generation
β”‚  β”œβ”€ EvidenceLogger - Audit logging
β”‚  β”œβ”€ Menu - User interface
β”‚  β”œβ”€ ConfigService - Configuration loading
β”‚  └─ FileService - File operations
β”‚
└─ Domain Models
   β”œβ”€ Config, Query, ReportMetadata
   β”œβ”€ ReportData, SystemInfo, QueryResult
   └─ ComplianceEvidence, ScanResult

Layer 6: Infrastructure
└─ External Dependencies
   β”œβ”€ golang.org/x/sys/windows/registry
   β”œβ”€ html/template
   β”œβ”€ log/slog
   └─ Standard library

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Dependency Direction                       β”‚
β”‚                                                                 β”‚
β”‚  Higher layers depend on lower layers                           β”‚
β”‚  All layers depend on interfaces (Layer 5 interfaces)           β”‚
β”‚  Lower layers have NO knowledge of higher layers                β”‚
β”‚  Follows Clean Architecture principles                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Testing Strategy Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Testing Pyramid                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

                           β–²
                          β•± β•²
                         β•±   β•²
                        β•±     β•²
                       β•±       β•²
                      β•±    E2E  β•²
                     β•±   Tests   β•²
                    ╱─────────────╲
                   β•±               β•²
                  β•±   Integration   β•²
                 β•±      Tests        β•²
                ╱─────────────────────╲
               β•±                       β•²
              β•±      Unit Tests         β•²
             β•±    (with mocks)           β•²
            ╱─────────────────────────────╲
           β•±_______________________________β•²


β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Unit Tests (70% of tests)                                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚  Test: ReportRunner.ExecuteReport()                              β”‚
β”‚  Mocks: MockRegistryService, MockConfigService,                 β”‚
β”‚         MockReportService, MockEvidenceService                   β”‚
β”‚  Assertion: Correct methods called with correct params          β”‚
β”‚                                                                  β”‚
β”‚  Test: HTMLReport.Generate()                                     β”‚
β”‚  Mocks: MockRegistryService                                      β”‚
β”‚  Assertion: HTML output matches expected template               β”‚
β”‚                                                                  β”‚
β”‚  Test: Dependencies.Validate()                                   β”‚
β”‚  Mocks: None (pure logic)                                        β”‚
β”‚  Assertion: Returns error when deps missing                     β”‚
β”‚                                                                  β”‚
β”‚  βœ… Fast execution (milliseconds)                               β”‚
β”‚  βœ… No external dependencies                                    β”‚
β”‚  βœ… High code coverage (target: 75%+)                           β”‚
β”‚  βœ… Isolated failure detection                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Integration Tests (20% of tests)                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚  Test: ReportRunner with Real RegistryReader                    β”‚
β”‚  Real: RegistryReader, FileSystem                               β”‚
β”‚  Mocks: None                                                     β”‚
β”‚  Assertion: Report generated with real registry data            β”‚
β”‚                                                                  β”‚
β”‚  Test: Full Report Generation Flow                              β”‚
β”‚  Real: All services                                              β”‚
β”‚  Mocks: None                                                     β”‚
β”‚  Assertion: HTML + Evidence files created correctly             β”‚
β”‚                                                                  β”‚
β”‚  ⚠️  Requires Windows environment                               β”‚
β”‚  ⚠️  Slower execution (seconds)                                 β”‚
β”‚  βœ… Tests real interactions                                     β”‚
β”‚  βœ… Catches integration issues                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ End-to-End Tests (10% of tests)                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚  Test: CLI - List Reports                                       β”‚
β”‚  Command: ./ComplianceToolkit.exe -list                         β”‚
β”‚  Assertion: All reports listed, exit code 0                     β”‚
β”‚                                                                  β”‚
β”‚  Test: CLI - Run Single Report                                  β”‚
β”‚  Command: ./ComplianceToolkit.exe -report=NIST_800_171.json     β”‚
β”‚  Assertion: HTML generated, evidence logged, exit code 0        β”‚
β”‚                                                                  β”‚
β”‚  Test: Interactive Mode - Run All Reports                       β”‚
β”‚  Input: Simulated user input (1 β†’ all reports β†’ 0)              β”‚
β”‚  Assertion: All reports completed, files created                β”‚
β”‚                                                                  β”‚
β”‚  ⚠️  Requires Windows + admin privileges                        β”‚
β”‚  ⚠️  Slowest execution (minutes)                                β”‚
β”‚  βœ… Tests complete user workflows                               β”‚
β”‚  βœ… Smoke tests for releases                                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Before/After Comparison

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  BEFORE (Current State)                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                β”‚
β”‚  main()                                                        β”‚
β”‚   └─ app := &App{...}                                          β”‚
β”‚       └─ app.init()                                            β”‚
β”‚           └─ slog.SetDefault(logger) ❌ GLOBAL STATE           β”‚
β”‚           └─ app.reader = pkg.NewRegistryReader(...)           β”‚
β”‚                                                                β”‚
β”‚  app.executeReport()                                           β”‚
β”‚   └─ htmlReport := pkg.NewHTMLReport(...)                      β”‚
β”‚   └─ htmlReport.SetRegistryReader(app.reader) ❌ SETTER        β”‚
β”‚   └─ evidence := pkg.NewEvidenceLogger(...)                    β”‚
β”‚   └─ evidence.GatherMachineInfo(app.reader)                    β”‚
β”‚                                                                β”‚
β”‚  Testing:                                                      β”‚
β”‚   ❌ Cannot mock RegistryReader                                β”‚
β”‚   ❌ Cannot test executeReport() in isolation                  β”‚
β”‚   ❌ Tests interfere with each other (global logger)           β”‚
β”‚   ❌ No interfaces to implement                                β”‚
β”‚                                                                β”‚
β”‚  Metrics:                                                      β”‚
β”‚   β€’ Test Coverage: 15%                                         β”‚
β”‚   β€’ Cyclomatic Complexity: 45                                  β”‚
β”‚   β€’ Coupling: High                                             β”‚
β”‚   β€’ Testability: Low                                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

                             ⬇️  REFACTORING  ⬇️

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   AFTER (Target State)                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                β”‚
β”‚  main()                                                        β”‚
β”‚   └─ logger := setupLogger(...) βœ… LOCAL SCOPE                 β”‚
β”‚   └─ deps := NewDependencies(config, logger)                   β”‚
β”‚   └─ app, err := NewApp(deps) βœ… CONSTRUCTOR INJECTION         β”‚
β”‚   └─ app.runInteractive()                                      β”‚
β”‚                                                                β”‚
β”‚  ReportRunner.ExecuteReport()                                  β”‚
β”‚   └─ reportSvc := factory.CreateReportService(...)             β”‚
β”‚   └─ evidenceSvc := factory.CreateEvidenceService(...)         β”‚
β”‚   └─ evidenceSvc.GatherMachineInfo(deps.RegistryService)       β”‚
β”‚   └─ reportSvc.Generate()                                      β”‚
β”‚                                                                β”‚
β”‚  Testing:                                                      β”‚
β”‚   βœ… Mock all interfaces easily                                β”‚
β”‚   βœ… Test any component in isolation                           β”‚
β”‚   βœ… Parallel test execution                                   β”‚
β”‚   βœ… 6 interfaces implemented                                  β”‚
β”‚                                                                β”‚
β”‚  Metrics:                                                      β”‚
β”‚   β€’ Test Coverage: 75%                                         β”‚
β”‚   β€’ Cyclomatic Complexity: 25                                  β”‚
β”‚   β€’ Coupling: Low                                              β”‚
β”‚   β€’ Testability: High                                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Migration Path

Week 1: Interfaces & Mocks
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. Create pkg/interfaces.go                                    β”‚
β”‚ 2. Create pkg/mocks/ directory                                 β”‚
β”‚ 3. Write MockRegistryService, MockReportService, etc.          β”‚
β”‚ 4. Write interface compliance tests                            β”‚
β”‚ 5. Verify existing code matches interfaces                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ⬇️
Week 2: Services
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. Create pkg/config_service.go                                β”‚
β”‚ 2. Create pkg/file_service.go                                  β”‚
β”‚ 3. Update pkg/htmlreport.go constructor                        β”‚
β”‚ 4. Update pkg/evidence.go constructor                          β”‚
β”‚ 5. Remove SetRegistryReader() method                           β”‚
β”‚ 6. Write unit tests for all services                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ⬇️
Week 3: Dependency Container
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. Create cmd/dependencies.go                                  β”‚
β”‚ 2. Create cmd/factory.go                                       β”‚
β”‚ 3. Update cmd/toolkit.go main()                                β”‚
β”‚ 4. Remove global logger (slog.SetDefault)                      β”‚
β”‚ 5. Update App struct                                            β”‚
β”‚ 6. Test with real dependencies                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ⬇️
Week 4: Report Runner
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. Refactor cmd/report_runner.go                               β”‚
β”‚ 2. Extract helper functions                                    β”‚
β”‚ 3. Remove executeReportQuiet() duplication                     β”‚
β”‚ 4. Write comprehensive unit tests                              β”‚
β”‚ 5. Integration tests with mocks                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ⬇️
Week 5: Integration
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. Update all App methods                                      β”‚
β”‚ 2. Remove old initialization code                              β”‚
β”‚ 3. Integration testing (Windows)                               β”‚
β”‚ 4. Regression testing (all reports)                            β”‚
β”‚ 5. Performance benchmarking                                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              ⬇️
Week 6: Polish & Documentation
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 1. Update CLAUDE.md                                            β”‚
β”‚ 2. Update ARCHITECTURE.md                                      β”‚
β”‚ 3. Add testing guide                                            β”‚
β”‚ 4. Code review & final adjustments                             β”‚
β”‚ 5. Merge to main branch                                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Success Criteria

βœ… All interfaces defined and documented βœ… All services implement interfaces correctly βœ… Zero global state (no slog.SetDefault()) βœ… Dependencies container validates all deps βœ… Factory creates all service instances βœ… Unit test coverage β‰₯ 75% βœ… All existing reports still work βœ… No performance regression (within 5%) βœ… Code complexity reduced (cyclomatic < 30) βœ… Documentation updated βœ… Rollback plan tested βœ… Team trained on new architecture